package org.cqust.backend.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.cqust.backend.common.ApiResult;
import org.cqust.backend.controller.base.BaseController;
import org.cqust.backend.dto.request.data.SaveUserSettingRequestDTO;
import org.cqust.backend.dto.request.data.SaveUserTopologyRequestDTO;
import org.cqust.backend.dto.response.data.UserSettingDTO;
import org.cqust.backend.dto.response.data.UserTopologyDTO;
import org.cqust.backend.entity.User;
import org.cqust.backend.service.DataService;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;


@RestController
@RequestMapping("/api/data")
public class DataController extends BaseController {
    private final DataService dataService;

    /**
     * 构造函数，初始化DataController。
     *
     * @param dataService 数据服务实例
     */
    public DataController(DataService dataService) {
        this.dataService = dataService;
    }

    /**
     * 获取用户设置的JSON数据。
     *
     * @return 包含用户设置JSON的ApiResult对象
     */
    @Operation(summary = "获取用户设置的JSON数据")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "成功获取用户设置JSON数据"),
        @ApiResponse(responseCode = "400", description = "用户未找到", content = @Content),
        @ApiResponse(responseCode = "500", description = "服务器内部错误", content = @Content)
    })
    @GetMapping("/getSettingJson")
    public ApiResult<UserSettingDTO> getSettingJson() {

        return ApiResult.success(new UserSettingDTO());
        // long userId = getUserId();
        // UserSettingDTO dto = dataService.getSettingJson(userId);
        // return ApiResult.success(dto);
    }

    /**
     * 保存用户设置的JSON数据。
     *
     * @param requestDTO 包含用户设置信息的请求DTO
     * @return 包含保存结果的ApiResult对象
     */
    @Operation(summary = "保存用户设置的JSON数据")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "用户设置JSON数据保存成功"),
        @ApiResponse(responseCode = "400", description = "请求参数无效", content = @Content),
        @ApiResponse(responseCode = "500", description = "服务器内部错误", content = @Content)
    })
    @PostMapping("/saveSettingJson")
    public ApiResult<String> saveSettingJson(
            @Parameter(description = "包含用户设置信息的请求DTO", required = true)
            @RequestBody SaveUserSettingRequestDTO requestDTO) {
        User user = getUser();
        if (requestDTO.getUserId() == null) {
            requestDTO.setUserId(user.getId());
        }else{
            authorityCheck(user, requestDTO.getUserId());
        }
        dataService.saveSettingJson(requestDTO);
        return ApiResult.success("保存成功");
    }

    /**
     * 获取拓扑结构的XML数据。
     *
     * @return 包含拓扑结构XML的ApiResult对象
     */
    @Operation(summary = "获取拓扑结构的XML数据")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "成功获取拓扑结构XML数据"),
        @ApiResponse(responseCode = "400", description = "用户未找到", content = @Content),
        @ApiResponse(responseCode = "500", description = "服务器内部错误", content = @Content)
    })
    @GetMapping("/getTopologyXml")
    public ApiResult<UserTopologyDTO> getTopologyXml() {
        long userId = getUserId();
        UserTopologyDTO dto = dataService.getTopologyXml(userId);
        return ApiResult.success(dto);
    }

    /**
     * 保存拓扑结构的XML数据。
     *
     * @param requestDTO 包含拓扑结构信息的请求DTO
     * @return 包含保存结果的ApiResult对象
     */
    @Operation(summary = "保存拓扑结构的XML数据")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "拓扑结构XML数据保存成功"),
        @ApiResponse(responseCode = "400", description = "请求参数无效", content = @Content),
        @ApiResponse(responseCode = "500", description = "服务器内部错误", content = @Content)
    })
    @PostMapping("/saveTopologyXml")
    public ApiResult<String> saveTopologyXml(@Parameter(description = "包含拓扑结构信息的请求DTO", required = true) @RequestBody SaveUserTopologyRequestDTO requestDTO) {
        User user = getUser();
        if (requestDTO.getUserId() == null) {
            requestDTO.setUserId(user.getId());
        }else{
            authorityCheck(user, requestDTO.getUserId());
        }
        dataService.saveTopologyXml(requestDTO);
        return ApiResult.success("保存成功");
    }

    /**
     * 权限检查，如果用户ID与当前用户ID不一致，并且当前用户不是老师，则抛出AccessDeniedException异常。
     * @param user 用户
     * @param userId 用户ID
     */
    private void authorityCheck(User user, Long userId){
        if (!Objects.equals(user.getId(), userId)) {
            if(user.getAuthorities().stream().anyMatch(o -> Objects.equals(o.getAuthority(), "Teacher")))
                throw new AccessDeniedException("无权限操作");
        }
    }
}
